package com.tydic.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tydic.borderer.domain.BorderAgent;
import com.tydic.borderer.domain.BordererInfo;
import com.tydic.borderer.domain.bo.AgainHistoryByPageBo;
import com.tydic.borderer.mapper.BorderAgentMapper;
import com.tydic.borderer.service.IBordererInfoService;
import com.tydic.common.core.domain.model.LoginUser;
import com.tydic.common.core.enums.*;
import com.tydic.common.core.exception.api.ApiException;
import com.tydic.common.satoken.utils.LoginHelper;
import com.tydic.common.web.domain.bo.DetailBo;
import com.tydic.product.domain.CarNumber;
import com.tydic.product.domain.Product;
import com.tydic.product.domain.ProductCost;
import com.tydic.product.domain.bo.ProductBo;
import com.tydic.product.domain.bo.ProductByPageBo;
import com.tydic.product.domain.bo.ProductGroupBo;
import com.tydic.product.domain.bo.StatusBo;
import com.tydic.product.domain.vo.ProductCalculateVo;
import com.tydic.product.domain.vo.ProductCategoryVo;
import com.tydic.product.domain.vo.ProductVo;
import com.tydic.product.mapper.ProductCostMapper;
import com.tydic.product.mapper.ProductMapper;
import com.tydic.product.service.ICarNumberService;
import com.tydic.product.service.IProductCostService;
import com.tydic.product.service.IProductService;
import com.tydic.product.utils.ProductCalculateUtils;
import com.tydic.system.service.ISysMessageService;
import com.tydic.workflow.service.IBpmService;
import com.tydic.workflow.service.IPublishProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Slf4j
@Service
public class ProductServiceImpl implements IProductService {
    private final ProductMapper productMapper;
    private final IProductCostService productCostService;
    private final IBordererInfoService bordererInfoService;
    private final IPublishProductService publishProductService;
    private final ISysMessageService messageService;
    private final ICarNumberService carNumberService;
    private final BorderAgentMapper borderAgentMapper;
    private final IBpmService bpmService;
    private final ProductCostMapper productCostMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteByParentProductId(String parentProductId) {
        return productMapper.delete(Wrappers.lambdaUpdate(Product.class).eq(Product::getParentProductId, parentProductId));
    }

    @Override
    public List<Product> findByParentProductId(String parentProductId) {
        return productMapper.selectList(Wrappers.lambdaQuery(Product.class).eq(Product::getParentProductId, parentProductId));
    }

    @Override
    public List<ProductVo> findVoByParentProductId(String parentProductId) {
        return findByParentProductId(parentProductId).stream().map(this::buildAppProductResult).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void auditAble(StatusBo request) {
        Product product = checkProductExist(request.getId());

        if (ProductGroupEnum.CHILD.equalsStatus(product.getGroupStatus())) {
            throw new ApiException("没有权限操作子商品!");
        }

        if (CharSequenceUtil.equals(AuditStatusEnum.SUCCESS.getStatus(), product.getAuditStatus())) {
            throw new ApiException("不可以重复审核!");
        }

        if (CharSequenceUtil.equals(AuditStatusEnum.FAIL.getStatus(), product.getAuditStatus())) {
            throw new ApiException("审核不通过，请重新发布商品!");
        }

        // 审核子商品
        if (ProductGroupEnum.PARENT.equalsStatus(product.getGroupStatus())) {
            findByParentProductId(product.getId()).forEach(item -> {
                auditAbleProduct(request, item);
            });
        }

        // 审核 parent 商品
        auditAbleProduct(request, product);

        publishProductService.submit(product.getProcInstId(), request.getComment(), request.isEnable());

        messageService.handleMessage(MessageCategoryEnum.PRODUCT, request.getId());
        if (!request.isEnable()) {
            Task task = bpmService.getTask(product.getProcInstId());
            messageService.insertMessageHandler(MessageCategoryEnum.PRODUCT, product.getId(), "商品待修改", "商品:" + product.getTitle(), task.getAssignee());
        }
    }

    private void auditAbleProduct(StatusBo request, Product product) {
        if (request.isEnable()) {
            product.setAuditStatus(AuditStatusEnum.SUCCESS.getStatus());
            product.setSale(ProductSaleStatus.SALE.getStatus());
        } else {
            product.setAuditStatus(AuditStatusEnum.FAIL.getStatus());
            product.setSale(ProductSaleStatus.TO_BE_PUBLISH.getStatus());
        }
        product.setRemarks(request.getComment());
        productMapper.insertOrUpdate(product);
    }

    @Override
    public int getNeedHandler() {
        LoginUser currentUser = LoginHelper.getLoginUser();
        if (UserTypeEnum.PLATFORM.equalsType(currentUser.getUserType())) {
            return productMapper.selectNeedHandler(currentUser.getUserCode()).size();
        } else {
            return productMapper.selectAllNeedHandler().size();
        }
    }

    @Override
    public List<ProductCategoryVo> queryProductType() {
        return productCostMapper.selectCategory();
    }

    @Override
    public Map<String, List<ProductCost>> getProductCostMap() {
        Map<String, List<ProductCost>> resultMap = new HashMap<>();
        List<ProductCost> productCostList = productCostService.selectList();
        productCostList.forEach(item -> {
            List<ProductCost> list = resultMap.get(item.getCategory());
            if (ObjectUtil.isNull(list)) {
                list = new ArrayList<>();
                resultMap.put(item.getCategory(), list);
            }
            list.add(item);
        });
        return resultMap;
    }

    @Override
    public ProductCalculateVo calculate(String price, String realPrice) {
        BigDecimal totalAmount = new BigDecimal(realPrice);
        // 税费
        BigDecimal taxationAmount = ProductCalculateUtils.calculateTaxation(totalAmount);
        // 服务费
        BigDecimal serviceChargeAmount = ProductCalculateUtils.calculateServiceCharge(taxationAmount);

        ProductCalculateVo resp = new ProductCalculateVo();
        resp.setTaxationAmount(ProductCalculateUtils.stripTrailingZerosString(taxationAmount));
        resp.setServiceChargeAmount(ProductCalculateUtils.stripTrailingZerosString(serviceChargeAmount.setScale(2, RoundingMode.HALF_UP)));

        // 利润
        if (CharSequenceUtil.isNotBlank(price)) {
            BigDecimal costAmount = new BigDecimal(price);
            BigDecimal profitAmount = totalAmount.subtract(costAmount).subtract(taxationAmount).subtract(serviceChargeAmount);
            resp.setProfitAmount(ProductCalculateUtils.stripTrailingZerosString(profitAmount.setScale(2, RoundingMode.HALF_UP)));
        }
        return resp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void publishProduct(ProductBo request) {
        LoginUser currentUser = LoginHelper.getLoginUser();
        BordererInfo bordererInfo = bordererInfoService.getBordererInfoByUserCode(currentUser.getUserCode());
        Product product = buildProduct(request, bordererInfo, ProductGroupEnum.DEFAULT);

        ProcessInstance processInstance = publishProductService.startProcess(product.getId());
        product.setProcInstId(processInstance.getProcessInstanceId());
        productMapper.insertOrUpdate(product);

        messageService.insertNeedHandler(MessageCategoryEnum.PRODUCT, product.getId(), "商品待审核", "商品:" + product.getTitle());
    }

    private Product buildProduct(ProductBo request, BordererInfo bordererInfo, ProductGroupEnum enableEnum) {
        Product product;
        if (StrUtil.isBlank(request.getId())) {
            product = new Product();
            product.setId(IdUtil.getSnowflakeNextIdStr());
            product.setNumber(product.getId());
        } else {
            product = productMapper.selectById(request.getId());
        }
        BeanUtil.copyProperties(request, product, "id", "number");
        product.setSale(ProductSaleStatus.OFF_SHELF.getStatus());
        product.setAuditStatus(AuditStatusEnum.READY.getStatus());
        product.setGroupStatus(enableEnum.getStatus());
        // 税费 服务费 利润
        BigDecimal price = new BigDecimal(request.getPrice()); // 成本
        BigDecimal realPrice = new BigDecimal(request.getRealPrice()); // 销售金额

        BigDecimal taxationAmount = ProductCalculateUtils.calculateTaxation(realPrice); // 税费
        BigDecimal serviceChargeAmount = ProductCalculateUtils.calculateServiceCharge(taxationAmount); // 服务费
        BigDecimal profitAmount = realPrice.subtract(price).subtract(taxationAmount).subtract(serviceChargeAmount); // 利润

        product.setQuantity(ProductCalculateUtils.stripTrailingZerosString(new BigDecimal(request.getQuantity())));
        product.setPrice(ProductCalculateUtils.stripTrailingZerosString(price));
        product.setRealPrice(ProductCalculateUtils.stripTrailingZerosString(realPrice));
        product.setTotalQuantity(ProductCalculateUtils.stripTrailingZerosString(request.getTotalQuantity()));
        product.setTotalPrice(ProductCalculateUtils.stripTrailingZerosString(request.getTotalPrice()));
        product.setTotalRealPrice(ProductCalculateUtils.stripTrailingZerosString(request.getTotalRealPrice()));

        product.setTaxation(taxationAmount);
        product.setServiceCharge(serviceChargeAmount);
        product.setProfit(profitAmount);

        product.setBordererInfoId(bordererInfo.getId());
        product.setBordererInfoName(bordererInfo.getName());
        product.setBordererInfoCardNumber(bordererInfo.getBordererCardNumber());

        product.setPosterList(JSONUtil.toJsonStr(request.getPosterList()));
        product.setDeclarationPhotoList(JSONUtil.toJsonStr(request.getDeclarationPhotoList()));

        product.setBorderIdCardNumber(bordererInfo.getIdCardNumber());
        product.setBorderPhoneNumber(bordererInfo.getPhoneNumber());
        product.setBordererGroup(bordererInfo.getBordererGroup());
        return product;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void publishGroupProduct(ProductGroupBo request) {
        LoginUser currentUser = LoginHelper.getLoginUser();
        BordererInfo bodererAgent = bordererInfoService.getBordererInfoByUserCode(currentUser.getUserCode());
        request.setTotalPrice(request.getPrice());
        request.setTotalRealPrice(request.getRealPrice());
        request.setTotalQuantity(request.getQuantity());
        Product parentProduct = buildProduct(request, bodererAgent, ProductGroupEnum.PARENT);

        parentProduct.setBorderGroupId(request.getBorderGroupId());
        parentProduct.setBorderAgentId(bodererAgent.getId());
        parentProduct.setBorderAgentName(bodererAgent.getName());
        parentProduct.setBorderAgentCardNumber(bodererAgent.getBordererCardNumber());

        ProcessInstance processInstance = publishProductService.startProcess(parentProduct.getId());
        parentProduct.setProcInstId(processInstance.getProcessInstanceId());
        productMapper.insertOrUpdate(parentProduct);

        messageService.insertNeedHandler(MessageCategoryEnum.PRODUCT, parentProduct.getId(), "商品待审核", "商品:" + parentProduct.getTitle());

        // 如果原来有子商品，把子商品删除
        deleteByParentProductId(parentProduct.getId());
        // 添加子商品
        List<String> childrenIds = request.getBordererIdList();
        int size = childrenIds.size();

        BigDecimal price = new BigDecimal(request.getPrice()).divide(new BigDecimal(size), 2, RoundingMode.HALF_UP);
        BigDecimal realPrice = new BigDecimal(request.getRealPrice()).divide(new BigDecimal(size), 2, RoundingMode.HALF_UP);
        BigDecimal quantity = new BigDecimal(request.getQuantity()).divide(new BigDecimal(size), 10, RoundingMode.HALF_UP);

        ProductGroupBo productBo = BeanUtil.toBean(request, ProductGroupBo.class);
        productBo.setPrice(ProductCalculateUtils.stripTrailingZerosString(price));
        productBo.setRealPrice(ProductCalculateUtils.stripTrailingZerosString(realPrice));
        productBo.setQuantity(ProductCalculateUtils.stripTrailingZerosString(quantity));

        for (int i = 0; i < size; i++) {
            int number = i + 1;
            String id = childrenIds.get(i);
            BordererInfo bordererInfo = bordererInfoService.getBordererInfoById(id);
            Product product = buildProduct(productBo, bordererInfo, ProductGroupEnum.CHILD);
            product.setNumber(parentProduct.getNumber() + "-" + number);
            product.setParentProductId(parentProduct.getId());
            product.setBorderAgentId(bodererAgent.getId());
            product.setBorderAgentName(bodererAgent.getName());
            product.setBorderAgentCardNumber(bodererAgent.getBordererCardNumber());
            productMapper.insertOrUpdate(product);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Product saveGroupProduct(ProductGroupBo request) {
        // 添加/修改 parent 商品
        LoginUser currentUser = LoginHelper.getLoginUser();
        BordererInfo bodererAgent = bordererInfoService.getBordererInfoByUserCode(currentUser.getUserCode());
        ProductGroupBo parentProductGroupRequest = BeanUtil.toBean(request, ProductGroupBo.class);
        // 边民数量
        List<String> bordererIds = request.getBordererIdList();
        int size = bordererIds.size();
        BigDecimal totalPrice = new BigDecimal(request.getPrice()).multiply(new BigDecimal(size));
        BigDecimal totalRealPrice = new BigDecimal(request.getRealPrice()).multiply(new BigDecimal(size));
        BigDecimal totalQuantity = new BigDecimal(request.getQuantity()).multiply(new BigDecimal(size));
        parentProductGroupRequest.setTotalPrice(ProductCalculateUtils.stripTrailingZerosString(totalPrice));
        parentProductGroupRequest.setTotalRealPrice(ProductCalculateUtils.stripTrailingZerosString(totalRealPrice));
        parentProductGroupRequest.setTotalQuantity(ProductCalculateUtils.stripTrailingZerosString(totalQuantity));
        Product parentProduct = buildProduct(parentProductGroupRequest, bodererAgent, ProductGroupEnum.PARENT);
        parentProduct.setBorderGroupId(request.getBorderGroupId());
        parentProduct.setBorderAgentId(bodererAgent.getId());
        parentProduct.setBorderAgentName(bodererAgent.getName());
        parentProduct.setBorderAgentCardNumber(bodererAgent.getBordererCardNumber());
        parentProduct.setSale(ProductSaleStatus.TO_BE_PUBLISH.getStatus());
        productMapper.insertOrUpdate(parentProduct);
        carNumberService.clear(parentProduct.getId(), CarNumberBusinessTypeEnum.PRODUCT.getType());
        List<String> carNumbers = request.getCarNumbers();
        if (CollUtil.isNotEmpty(carNumbers)) {
            for (String carNumber : carNumbers) {
                carNumberService.save(parentProduct.getId(), CarNumberBusinessTypeEnum.PRODUCT.getType(), carNumber);
            }
        }
        deleteByParentProductId(parentProduct.getId());

        ProductGroupBo productBo = BeanUtil.toBean(request, ProductGroupBo.class, CopyOptions.create().setIgnoreProperties("id", "number"));
        productBo.setTotalQuantity(productBo.getQuantity());
        productBo.setTotalRealPrice(productBo.getRealPrice());
        productBo.setTotalPrice(productBo.getPrice());
        for (int i = 0; i < size; i++) {
            int number = i + 1;
            String id = bordererIds.get(i);
            BordererInfo bordererInfo = bordererInfoService.getBordererInfoById(id);
            Product product = buildProduct(productBo, bordererInfo, ProductGroupEnum.CHILD);
            product.setNumber(parentProduct.getNumber() + "-" + number);
            product.setParentProductId(parentProduct.getId());
            product.setBorderAgentId(bodererAgent.getId());
            product.setBorderAgentName(bodererAgent.getName());
            product.setBorderAgentCardNumber(bodererAgent.getBordererCardNumber());
            product.setSale(ProductSaleStatus.TO_BE_PUBLISH.getStatus());
            productMapper.insertOrUpdate(product);
        }
        return parentProduct;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editProduct(ProductBo productBo) {
        Product product = productMapper.selectById(productBo.getId());
        if (product == null) {
            throw new ApiException("该商品不存在");
        }
        if (!StrUtil.equals(product.getGroupStatus(), ProductGroupEnum.CHILD.getStatus())) {
            throw new ApiException("该商品不是子商品，无法编辑");
        }
        if (!StrUtil.equals(product.getSale(), ProductSaleStatus.TO_BE_PUBLISH.getStatus())) {
            throw new ApiException("该商品已发布，无法编辑");
        }
        // 更新后的税费 服务费 利润
        BigDecimal price = new BigDecimal(productBo.getPrice()); // 成本
        BigDecimal realPrice = new BigDecimal(productBo.getRealPrice()); // 销售金额
        BigDecimal taxationAmount = ProductCalculateUtils.calculateTaxation(realPrice); // 税费
        BigDecimal serviceChargeAmount = ProductCalculateUtils.calculateServiceCharge(taxationAmount); // 服务费
        BigDecimal profitAmount = realPrice.subtract(price).subtract(taxationAmount).subtract(serviceChargeAmount); // 利润
        product.setQuantity(productBo.getQuantity());
        product.setPrice(ProductCalculateUtils.stripTrailingZerosString(price));
        product.setRealPrice(ProductCalculateUtils.stripTrailingZerosString(realPrice));
        product.setTotalQuantity(ProductCalculateUtils.stripTrailingZerosString(productBo.getQuantity()));
        product.setTotalPrice(ProductCalculateUtils.stripTrailingZerosString(productBo.getPrice()));
        product.setTotalRealPrice(ProductCalculateUtils.stripTrailingZerosString(productBo.getRealPrice()));
        product.setTaxation(taxationAmount);
        product.setServiceCharge(serviceChargeAmount);
        product.setProfit(profitAmount);
        productMapper.insertOrUpdate(product);
        Product parentProduct = productMapper.selectById(product.getParentProductId());
        List<Product> children = findByParentProductId(product.getParentProductId());
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal totalRealPrice = new BigDecimal(0);
        BigDecimal totalQuantity = new BigDecimal(0);
        for (Product child : children) {
            totalPrice = totalPrice.add(new BigDecimal(child.getTotalPrice()));
            totalRealPrice = totalRealPrice.add(new BigDecimal(child.getTotalRealPrice()));
            totalQuantity = totalQuantity.add(new BigDecimal(child.getTotalQuantity()));
        }
        BigDecimal totalTaxationAmount = ProductCalculateUtils.calculateTaxation(totalRealPrice);
        BigDecimal totalServiceChargeAmount = ProductCalculateUtils.calculateServiceCharge(totalTaxationAmount);
        BigDecimal totalProfitAmount = totalRealPrice.subtract(totalPrice).subtract(totalTaxationAmount).subtract(totalServiceChargeAmount);
        parentProduct.setTotalPrice(ProductCalculateUtils.stripTrailingZerosString(totalPrice));
        parentProduct.setTotalRealPrice(ProductCalculateUtils.stripTrailingZerosString(totalRealPrice));
        parentProduct.setTotalQuantity(ProductCalculateUtils.stripTrailingZerosString(totalQuantity));
        parentProduct.setTaxation(totalTaxationAmount);
        parentProduct.setServiceCharge(totalServiceChargeAmount);
        parentProduct.setProfit(totalProfitAmount);
        productMapper.insertOrUpdate(parentProduct);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void publishGroupProduct(String id) {
        Product parentProduct = productMapper.selectById(id);
        if (parentProduct == null) {
            throw new ApiException("发布失败，该商品不存在");
        }
        if (!StrUtil.equals(parentProduct.getGroupStatus(), ProductGroupEnum.PARENT.getStatus())) {
            throw new ApiException("该商品不是总商品，无法发布");
        }
        if (!StrUtil.equals(parentProduct.getSale(), ProductSaleStatus.TO_BE_PUBLISH.getStatus())) {
            throw new ApiException("该商品已发布");
        }
        parentProduct.setSale(ProductSaleStatus.OFF_SHELF.getStatus());
        if (StrUtil.isBlank(parentProduct.getProcInstId())) {
            ProcessInstance processInstance = publishProductService.startProcess(parentProduct.getId());
            parentProduct.setProcInstId(processInstance.getProcessInstanceId());
        } else {
            publishProductService.submit(parentProduct.getProcInstId(), "通过", true);
        }
        productMapper.insertOrUpdate(parentProduct);
        messageService.insertNeedHandler(MessageCategoryEnum.PRODUCT, parentProduct.getId(), "商品待审核", "商品:" + parentProduct.getTitle());
        List<Product> children = findByParentProductId(id);
        for (Product child : children) {
            child.setSale(ProductSaleStatus.OFF_SHELF.getStatus());
            productMapper.insertOrUpdate(child);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saleAble(StatusBo request) {
        Product product = checkProductExist(request.getId());

        if (ProductGroupEnum.CHILD.equalsStatus(product.getGroupStatus())) {
            throw new ApiException("没有权限操作子商品!");
        }

        if (!CharSequenceUtil.equals(product.getAuditStatus(), AuditStatusEnum.SUCCESS.getStatus())) {
            throw new ApiException("商品没有审核通过，禁止当前操作!");
        }

        // 子商品上架/下架
        if (ProductGroupEnum.PARENT.equalsStatus(product.getGroupStatus())) {
            List<Product> children = findByParentProductId(product.getId());
            children.forEach(item -> {
                item.setSale(request.isEnable() ? ProductSaleStatus.SALE.getStatus() : ProductSaleStatus.OFF_SHELF.getStatus());
            });
            productMapper.updateBatchById(children);
        }

        product.setSale(request.isEnable() ? ProductSaleStatus.SALE.getStatus() : ProductSaleStatus.OFF_SHELF.getStatus());
        productMapper.insertOrUpdate(product);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(DetailBo request) {
        Product product = productMapper.selectById(request.getId());
        if (ProductGroupEnum.CHILD.equalsStatus(product.getGroupStatus())) {
            throw new ApiException("不可以删除子商品!");
        }
        // 删除边民组子商品
        if (ProductGroupEnum.PARENT.equalsStatus(product.getGroupStatus())) {
            deleteByParentProductId(product.getId());
        }
        productMapper.deleteById(request.getId());
    }

    private ProductVo buildAppProductResult(Product product) {
        ProductVo result = BeanUtil.copyProperties(product, ProductVo.class);
        if (CharSequenceUtil.isNotBlank(product.getPosterList())) {
            result.setPosterList(JSONUtil.toList(product.getPosterList(), String.class));
        }
        if (CharSequenceUtil.isNotBlank(product.getDeclarationPhotoList())) {
            result.setDeclarationPhotoList(JSONUtil.toList(product.getDeclarationPhotoList(), String.class));
        }
        return result;
    }


    @Override
    public ProductVo getProduct(DetailBo request) {
        Product product = productMapper.selectById(request.getId());
        if (ObjectUtil.isNull(product)) {
            throw new ApiException("商品不存在!");
        } else {
            ProductVo result = buildAppProductResult(product);
            // 查下子商品
            if (ProductGroupEnum.PARENT.equalsStatus(product.getGroupStatus())) {
                DetailBo detailRequest = new DetailBo();
                detailRequest.setId(product.getId());
                List<ProductVo> children = getChildren(detailRequest);
                result.setChildren(children);
                List<String> bordererInfoIds = children.stream().map(ProductVo::getBordererInfoId).collect(Collectors.toList());
                List<BordererInfo> bordererInfos = bordererInfoService.findByIds(bordererInfoIds);
                result.setBordererInfos(bordererInfos);
                List<String> carNumbers = carNumberService.list(product.getId(), CarNumberBusinessTypeEnum.PRODUCT.getType()).stream().map(CarNumber::getCarNumber).collect(Collectors.toList());
                result.setBordererCarNumbers(carNumbers);
            } else {
                List<BordererInfo> bordererInfos = bordererInfoService.findByIds(CollUtil.newArrayList(product.getBordererInfoId()));
                result.setBordererInfos(bordererInfos);
                List<String> carNumbers = carNumberService.list(product.getParentProductId(), CarNumberBusinessTypeEnum.PRODUCT.getType()).stream().map(CarNumber::getCarNumber).collect(Collectors.toList());
                result.setBordererCarNumbers(carNumbers);
            }
            return result;
        }
    }

    private LambdaQueryWrapper<Product> buildLambdaQueryWrapper(Product product) {
        LambdaQueryWrapper<Product> lqw = Wrappers.lambdaQuery(Product.class);
        lqw.like(CharSequenceUtil.isNotBlank(product.getTitle()), Product::getTitle, product.getTitle());
        lqw.like(CharSequenceUtil.isNotBlank(product.getProductCostCategory()), Product::getProductCostCategory, product.getProductCostCategory());
        lqw.like(CharSequenceUtil.isNotBlank(product.getProductCostName()), Product::getProductCostName, product.getProductCostName());
        lqw.like(CharSequenceUtil.isNotBlank(product.getNumber()), Product::getNumber, product.getNumber());
        lqw.like(CharSequenceUtil.isNotBlank(product.getDeclarationNumber()), Product::getDeclarationNumber, product.getDeclarationNumber());
        lqw.like(CharSequenceUtil.isNotBlank(product.getBordererInfoName()), Product::getBordererInfoName, product.getBordererInfoName());
        lqw.eq(CharSequenceUtil.isNotBlank(product.getAuditStatus()), Product::getAuditStatus, product.getAuditStatus());
        lqw.eq(CharSequenceUtil.isNotBlank(product.getSale()), Product::getSale, product.getSale());
        lqw.like(CharSequenceUtil.isNotBlank(product.getBordererGroup()), Product::getBordererGroup, product.getBordererGroup());
        lqw.like(CharSequenceUtil.isNotBlank(product.getBorderAgentName()), Product::getBorderAgentName, product.getBorderAgentName());
        lqw.eq(CharSequenceUtil.isNotBlank(product.getBorderAgentId()), Product::getBorderAgentId, product.getBorderAgentId());
        lqw.eq(CharSequenceUtil.isNotBlank(product.getBordererInfoId()), Product::getBordererInfoId, product.getBordererInfoId());
        lqw.eq(CharSequenceUtil.isNotBlank(product.getGroupStatus()), Product::getGroupStatus, product.getGroupStatus());
        lqw.ge(product.getCreateDate() != null, Product::getCreateDate, product.getCreateDate());
        lqw.orderByDesc(Product::getCreateDate);
        return lqw;
    }

    @Override
    public Page<ProductVo> findPage(ProductByPageBo request) {
        Product query = BeanUtil.copyProperties(request, Product.class);
        Page<Product> page = productMapper.selectPage(request.build(), buildLambdaQueryWrapper(query));
        List<ProductVo> records = page.getRecords().stream().map(item -> {
            ProductVo productResp = buildAppProductResult(item);
            if (ProductGroupEnum.PARENT.equalsStatus(item.getGroupStatus())) {
                DetailBo detailRequest = new DetailBo();
                detailRequest.setId(item.getId());
                List<ProductVo> children = getChildren(detailRequest);
                productResp.setChildren(children);
                List<String> bordererInfoIds = children.stream().map(ProductVo::getBordererInfoId).collect(Collectors.toList());
                List<BordererInfo> bordererInfos = bordererInfoService.findByIds(bordererInfoIds);
                productResp.setBordererInfos(bordererInfos);
                StringBuilder stringBuilder = new StringBuilder();
                for (BordererInfo bordererInfo : bordererInfos) {
                    stringBuilder.append(bordererInfo.getName()).append(",");
                }
                String borderName = stringBuilder.substring(0, stringBuilder.lastIndexOf(","));
                productResp.setBordererInfoName(borderName);
            } else {
                List<BordererInfo> bordererInfos = bordererInfoService.findByIds(CollUtil.newArrayList(item.getBordererInfoId()));
                productResp.setBordererInfos(bordererInfos);
                StringBuilder stringBuilder = new StringBuilder();
                for (BordererInfo bordererInfo : bordererInfos) {
                    stringBuilder.append(bordererInfo.getName()).append(",");
                }
                if (StrUtil.isNotBlank(stringBuilder)) {
                    String borderName = stringBuilder.substring(0, stringBuilder.lastIndexOf(","));
                    productResp.setBordererInfoName(borderName);
                }
            }
            return productResp;
        }).collect(Collectors.toList());
        Page<ProductVo> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        result.setRecords(records);
        return result;

    }

    @Override
    public List<ProductVo> getChildren(DetailBo request) {
        return productMapper.selectList(Wrappers.lambdaQuery(Product.class).eq(Product::getParentProductId, request.getId())).stream().map(this::buildAppProductResult).collect(Collectors.toList());
    }

    @Override
    public Page<ProductVo> getAgentProductHistory(AgainHistoryByPageBo request) {
        LoginUser currentUser = LoginHelper.getLoginUser();
        // 获取边民信息
        BordererInfo bordererInfo = bordererInfoService.getBordererInfoByUserCode(currentUser.getUserCode());
        Product product = new Product();
        product.setGroupStatus(ProductGroupEnum.CHILD.getStatus());
        if (UserTypeEnum.BORDERER_AGENT.equalsType(currentUser.getUserType())) {
            product.setBordererInfoId(request.getBorderId());
            product.setBorderAgentId(bordererInfo.getId());
        } else if (UserTypeEnum.BORDERER.equalsType(currentUser.getUserType())) {
            // 获取边民和边民代表的关联信息
            BorderAgent borderAgent = borderAgentMapper.selectOne(new LambdaQueryWrapper<BorderAgent>().eq(BorderAgent::getBordererId, bordererInfo.getId()).eq(BorderAgent::getApplyStatus, AgentApplyStatusEnum.AGREE.getStatus()));
            product.setBordererInfoId(bordererInfo.getId());
            product.setBorderAgentId(borderAgent.getAgentBordererId());
        }
        LambdaQueryWrapper<Product> lqw = buildLambdaQueryWrapper(product);
        Page<Product> productPage = productMapper.selectPage(request.build(), lqw);
        List<ProductVo> result = productPage.getRecords().stream().map(item -> {
            ProductVo productResp = buildAppProductResult(item);
            if (ProductGroupEnum.PARENT.equalsStatus(item.getGroupStatus())) {
                DetailBo detailRequest = new DetailBo();
                detailRequest.setId(item.getId());
                List<ProductVo> children = getChildren(detailRequest);
                productResp.setChildren(children);

                List<String> bordererInfoIds = children.stream().map(ProductVo::getBordererInfoId).collect(Collectors.toList());
                List<BordererInfo> bordererInfos = bordererInfoService.findByIds(bordererInfoIds);
                productResp.setBordererInfos(bordererInfos);

                StringBuilder stringBuilder = new StringBuilder();
                for (ProductVo child : children) {
                    stringBuilder.append(child.getBordererInfoName()).append(",");
                }

                String borderName = stringBuilder.substring(0, stringBuilder.lastIndexOf(","));
                productResp.setBordererInfoName(borderName);
            }
            return productResp;
        }).collect(Collectors.toList());
        Page<ProductVo> page = new Page<>(productPage.getCurrent(), productPage.getSize(), productPage.getTotal());
        page.setRecords(result);
        return page;
    }

    @Override
    public Product checkProductExist(String id) {
        Product product = productMapper.selectById(id);
        if (ObjectUtil.isNull(product)) {
            throw new ApiException("商品不存在!");
        }
        return product;
    }

    @Override
    public Product get(String id) {
        return productMapper.selectById(id);
    }
}
